<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Image Registration</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="summary">
<a href="#nested-classes">Classes</a>  </div>
  <div class="headertitle">
<div class="title">Image Registration</div>  </div>
</div><!--header-->
<div class="contents">
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../d3/d3c/classcv_1_1reg_1_1Map.html">cv::reg::Map</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Base class for modelling a <a class="el" href="../../d3/d3c/classcv_1_1reg_1_1Map.html" title="Base class for modelling a Map between two images. ">Map</a> between two images.  <a href="../../d3/d3c/classcv_1_1reg_1_1Map.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../d9/de5/classcv_1_1reg_1_1MapAffine.html">cv::reg::MapAffine</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../d0/d6c/classcv_1_1reg_1_1Mapper.html">cv::reg::Mapper</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Base class for modelling an algorithm for calculating a map.  <a href="../../d0/d6c/classcv_1_1reg_1_1Mapper.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../d0/d89/classcv_1_1reg_1_1MapperGradAffine.html">cv::reg::MapperGradAffine</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../d9/d51/classcv_1_1reg_1_1MapperGradEuclid.html">cv::reg::MapperGradEuclid</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../d7/db1/classcv_1_1reg_1_1MapperGradProj.html">cv::reg::MapperGradProj</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../df/d24/classcv_1_1reg_1_1MapperGradShift.html">cv::reg::MapperGradShift</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../de/d4c/classcv_1_1reg_1_1MapperGradSimilar.html">cv::reg::MapperGradSimilar</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../db/d6a/classcv_1_1reg_1_1MapperPyramid.html">cv::reg::MapperPyramid</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../d2/dcd/classcv_1_1reg_1_1MapProjec.html">cv::reg::MapProjec</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../d4/d53/classcv_1_1reg_1_1MapShift.html">cv::reg::MapShift</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="../../da/d1b/classcv_1_1reg_1_1MapTypeCaster.html">cv::reg::MapTypeCaster</a></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<p>The Registration module implements parametric image registration. The implemented method is direct alignment, that is, it uses directly the pixel values for calculating the registration between a pair of images, as opposed to feature-based registration. The implementation follows essentially the corresponding part of <a class="el" href="../../d0/de3/citelist.html#CITEREF_Szeliski06">[235]</a> .</p>
<p>Feature based methods have some advantages over pixel based methods when we are trying to register pictures that have been shoot under different lighting conditions or exposition times, or when the images overlap only partially. On the other hand, the main advantage of pixel-based methods when compared to feature based methods is their better precision for some pictures (those shoot under similar lighting conditions and that have a significative overlap), due to the fact that we are using all the information available in the image, which allows us to achieve subpixel accuracy. This is particularly important for certain applications like multi-frame denoising or super-resolution.</p>
<p>In fact, pixel and feature registration methods can complement each other: an application could first obtain a coarse registration using features and then refine the registration using a pixel based method on the overlapping area of the images. The code developed allows this use case.</p>
<p>The module implements classes derived from the abstract classes <a class="el" href="../../d3/d3c/classcv_1_1reg_1_1Map.html" title="Base class for modelling a Map between two images. ">cv::reg::Map</a> or <a class="el" href="../../d0/d6c/classcv_1_1reg_1_1Mapper.html" title="Base class for modelling an algorithm for calculating a map. ">cv::reg::Mapper</a>. The former models a coordinate transformation between two reference frames, while the later encapsulates a way of invoking a method that calculates a <a class="el" href="../../d3/d3c/classcv_1_1reg_1_1Map.html" title="Base class for modelling a Map between two images. ">Map</a> between two images. Although the objective has been to implement pixel based methods, the module can be extended to support other methods that can calculate transformations between images (feature methods, optical flow, etc.).</p>
<p>Each class derived from <a class="el" href="../../d3/d3c/classcv_1_1reg_1_1Map.html" title="Base class for modelling a Map between two images. ">Map</a> implements a motion model, as follows:</p>
<ul>
<li><a class="el" href="../../d4/d53/classcv_1_1reg_1_1MapShift.html">MapShift</a>: Models a simple translation</li>
<li><a class="el" href="../../d9/de5/classcv_1_1reg_1_1MapAffine.html">MapAffine</a>: Models an affine transformation</li>
<li><a class="el" href="../../d2/dcd/classcv_1_1reg_1_1MapProjec.html">MapProjec</a>: Models a projective transformation</li>
</ul>
<p>MapProject can also be used to model affine motion or translations, but some operations on it are more costly, and that is the reason for defining the other two classes.</p>
<p>The classes derived from <a class="el" href="../../d0/d6c/classcv_1_1reg_1_1Mapper.html" title="Base class for modelling an algorithm for calculating a map. ">Mapper</a> are</p>
<ul>
<li><a class="el" href="../../df/d24/classcv_1_1reg_1_1MapperGradShift.html">MapperGradShift</a>: Gradient based alignment for calculating translations. It produces a <a class="el" href="../../d4/d53/classcv_1_1reg_1_1MapShift.html">MapShift</a> (two parameters that correspond to the shift vector).</li>
<li><a class="el" href="../../d9/d51/classcv_1_1reg_1_1MapperGradEuclid.html">MapperGradEuclid</a>: Gradient based alignment for euclidean motions, that is, rotations and translations. It calculates three parameters (angle and shift vector), although the result is stored in a <a class="el" href="../../d9/de5/classcv_1_1reg_1_1MapAffine.html">MapAffine</a> object for convenience.</li>
<li><a class="el" href="../../de/d4c/classcv_1_1reg_1_1MapperGradSimilar.html">MapperGradSimilar</a>: Gradient based alignment for calculating similarities, which adds scaling to the euclidean motion. It calculates four parameters (two for the anti-symmetric matrix and two for the shift vector), although the result is stored in a <a class="el" href="../../d9/de5/classcv_1_1reg_1_1MapAffine.html">MapAffine</a> object for better convenience.</li>
<li><a class="el" href="../../d0/d89/classcv_1_1reg_1_1MapperGradAffine.html">MapperGradAffine</a>: Gradient based alignment for an affine motion model. The number of parameters is six and the result is stored in a <a class="el" href="../../d9/de5/classcv_1_1reg_1_1MapAffine.html">MapAffine</a> object.</li>
<li><a class="el" href="../../d7/db1/classcv_1_1reg_1_1MapperGradProj.html">MapperGradProj</a>: Gradient based alignment for calculating projective transformations. The number of parameters is eight and the result is stored in a MapProject object.</li>
<li><a class="el" href="../../db/d6a/classcv_1_1reg_1_1MapperPyramid.html">MapperPyramid</a>: It implements hyerarchical motion estimation using a Gaussian pyramid. Its constructor accepts as argument any other object that implements the <a class="el" href="../../d0/d6c/classcv_1_1reg_1_1Mapper.html" title="Base class for modelling an algorithm for calculating a map. ">Mapper</a> interface, and it is that mapper the one called by <a class="el" href="../../db/d6a/classcv_1_1reg_1_1MapperPyramid.html">MapperPyramid</a> for each scale of the pyramid.</li>
</ul>
<p>If the motion between the images is not very small, the normal way of using these classes is to create a MapperGrad* object and use it as input to create a <a class="el" href="../../db/d6a/classcv_1_1reg_1_1MapperPyramid.html">MapperPyramid</a>, which in turn is called to perform the calculation. However, if the motion between the images is small enough, we can use directly the MapperGrad* classes. Another possibility is to use first a feature based method to perform a coarse registration and then do a refinement through <a class="el" href="../../db/d6a/classcv_1_1reg_1_1MapperPyramid.html">MapperPyramid</a> or directly a MapperGrad* object. The "calculate" method of the mappers accepts an initial estimation of the motion as input.</p>
<p>When deciding which MapperGrad to use we must take into account that mappers with more parameters can handle more complex motions, but involve more calculations and are therefore slower. Also, if we are confident on the motion model that is followed by the sequence, increasing the number of parameters beyond what we need will decrease the accuracy: it is better to use the least number of degrees of freedom that we can.</p>
<p>In the module tests there are examples that show how to register a pair of images using any of the implemented mappers. </p>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:41 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
